// =====================================================================================
// 
//       Filename:  pathutils.h
// 
//    Description:  Definition of functions operating on path names
// 
//        Version:  1.0
//        Created:  03/10/2010 14:28:22
//       Revision:  none
//       Compiler:  gcc
// 
//         Author:  François Hissel (fh), francois.hissel@m4x.org
//        Company:  
// 
// =====================================================================================

#ifndef  PATHUTILS_INC
#define  PATHUTILS_INC

#include	<unistd.h>
#include	<time.h>

/**
 * \brief Description of a file in a virtual drive
 *
 * This structure describes a file on the remote server. Each file is associated with its virtual name, its type (folder or normal file), and the path it may be accessed on.
 */
typedef struct Item {
	char *name;	//!< Name of the file
	enum ItemType {T_FILE,T_FOLDER} type;	//!< Type of the file
	char *path;	//!< Path of the file on the remote server
	char *requesturi;	//!< URi of the requests for a folder
	int id;	//!< Local file ID for a file, initially 0 but takes a non-null value when the file is copied to the cache
	ssize_t size;	//!< Size of the file
	time_t date;	//!< Date of last modification of the file
	int updated;	//!< Indicate if the structure has been updated recently by loading it from the disk (1 if yes, 0 if no)
} Item;

/**
 * \brief List of files
 *
 * This structure is used to hold a chained list of files. Each file has a name, a type (folder, normal file). It is a part of a path description structure, used to describe one folder.
 */
typedef struct Folder {
	Item *file;	//!< Description of the file
	struct Folder *parent;	//!< Parent folder of this one, 0 for a root
	struct Folder *elements;	//!< For a folder, list of elements it contains. For a normal file, this variable should be null
	struct Folder *next;	//!< Next item of the folder, 0 if the last item is reached
} Folder;

/**
 * \brief Reduce a path name by removing "." and ".." directories
 *
 * This function simplifies a path name by removing instances of "." and ".." directories. "." directories are simply ignored, while ".." directories make the path go back to the parent directory. It is assumed that the base path name is an absolute path name, and not a relative one.
 * \param pathname Initial path name
 * \param newname Simplified path name returned by the function. The memory should already be allocated before the call to the function
 */
void path_simplify(const char *pathname,char *newname);

/**
 * \brief Get the parent directory of a path name, that is the first one in the name
 *
 * This function gets the highest-level directory from a path name, beginning at the pointer pathname. It outputs the directory name in the name argument
 * \param pathname Path name. For better performance, consider simplifying it with path_simplify before analyzing it with this routine. At the end of the function, this variable points to the start of the new directory if there is one, so that the function can immediatly be called again to get the next directory in the path. If the pointer refers to the end of the string, it means the name which has just been read is actually a file name.
 * \param name Name of the next directory in the path. The memory should already be allocated before the call to the function
 */
void get_dir(const char **pathname,char *name);

/**
 * \brief Extract file path and file name from a full path
 *
 * This functions extracts the folder name and the file name from a full path name. If one of the parameters folder and name has a zero value, the function will not try to fill it with a folder or file name.
 * \param path Full path name
 * \param folder Folder name of the file
 * \param name File name
 */
void get_path_and_name(const char *path,char *folder,char *name);

/**
 * \brief Decode an HTML text by replacing HTML entities with UTF-8 characters
 *
 * This function decodes the initial HTML string and copies it to the destination string after having replaced the HTML entities by UTF-8 characters
 * \param source Source string, in HTML format
 * \param dest Destination string, should already be allocated before the call to the function and have a size sufficient to hold the whole converted string
 */
void html_to_text(const char *source,char *dest);

/**
 * \brief Encode a UTF-8 text in HTML, using standard entities
 *
 * This function encodes the initial string and copies it to the destination string in an HTML format
 * \param source Source string
 * \param dest Destination string, should already be allocated before the call to the function and have a size sufficient to hold the whole converted string
 */
void text_to_html(const char *source,char *dest);

/**
 * \brief Free a folder item
 *
 * This function reclaims the memory used to hold a file. It also frees the memory allocated for its name and virtual path.
 * \param item Item which will be removed
 */
void free_item(Item *item);

/**
 * \brief Create a new empty folder
 *
 * This function creates a new variable of type Folder and initialize it with null values. It also allocates the memory needed by the variable, and returns a pointer to a new structure
 * \param parent Parent folder of this one
 * \return Pointer to a new empty Folder structure
 */
Folder *create_folder(Folder *parent);

/**
 * \brief Free a list of files
 *
 * This function reclaims the memory used to hold a folder and all its subfolders. Every item of the folder is erased.
 * \param folder Base of the tree which has to be erased
 */
void free_folder(Folder *folder);

/**
 * \brief Find a file in a folder
 *
 * This function looks for a file with a given name in the folder. Only the root folder is searched, the function does not recurse in subfolders. The function is case sensitive. If a file is found, a pointer to the item is returned. If not, the function returns a null pointer.
 * \param folder Folder which will be searched
 * \param name Name of the file or folder
 * \return 0 if the file was not found, a pointer to the item if it was found
 */
Folder *find_item(Folder *folder,char *name);

/**
 * \brief Add an element to a folder
 *
 * This function adds an element to the specified folder. It does not try to sort the folder, since the sorting order is unknown.
 * \param folder Folder in the elements of which the new element will be added
 * \param name Name of the element
 * \param type Type of the element
 * \param path Full remote path of the element
 * \return Folder structure of the new element
 */
Folder* add_element(Folder *folder,char *name,enum ItemType type,const char *path);

/**
 * \brief Remove an element from a folder
 *
 * This function removes an element from a folder. It looks for the name of this element and, if it is found, remove the element from the children of the folder.
 * \param folder Folder from which the element will be removed
 * \param name Name of the element to remove
 */
void remove_element(Folder *folder,char *name);

/**
 * \brief Get the ID number of an item
 *
 * This function retrieves the remote server internal ID for an element, whether a file or a folder. This ID is the last number of several figures in its web address. The ID is saved in the id variable. The function returns 0 if everything went fine, and another value otherwise.
 * \param folder Folder which ID will be retrieved
 * \param id After the end of the function, holds the ID of the element. The buffer should be allocated before the function call and have a sufficient size
 * \return 0 if everything went fine, another value otherwise
 */
int get_id(Folder *folder,char *id);

#endif   // ----- #ifndef PATHUTILS_INC  -----

